#include "render2d.h"

Render2D::Render2D(QWidget *parent)
	: QWidget(parent)
	, scaleFactor(5.0)
	, viewPos(0.0, 0.0)
	, traceShip(true)
	, printsNum(200)
	, printsDT(5.0)
{
	setBackgroundRole(QPalette::Base);
    setAutoFillBackground(true);

	startTimer(50);

	QPainterPath bow;

	bow.moveTo(1.19964, -11.15686);
	bow.cubicTo(1.053, -11.38306, 0.88166, -11.7364, 0.77298, -12.0978);
	bow.cubicTo(0.59228, -12.69944, 0.29614, -13, 0, -13);
	bow.cubicTo(-0.29614, -13, -0.59228, -12.69944, -0.77298, -12.0978);
	bow.cubicTo(-0.88166, -11.7364, -1.053, -11.38306, -1.19964, -11.15686);
	bow.cubicTo(-0.96122, -11.4946, -0.71682, -11.75122, -0.47268, -11.90072);
	bow.cubicTo(-0.3146, -11.9977, -0.15652, -12.04944, 0, -12.04944);
	bow.cubicTo(0.15652, -12.04944, 0.3146, -11.9977, 0.47268, -11.90072);
	bow.cubicTo(0.71682, -11.75122, 0.96122, -11.4946, 1.19964, -11.15686);

	shipView.push_back(ShipViewElement(bow, QColor(Qt::black), QPen(QColor(Qt::black),0.208)));

	QPainterPath hull;

	hull.moveTo(0, 13);
	hull.cubicTo(-2.06206, 13, -2.70296, 10.7172, -3.07996, 7.14766);
	hull.cubicTo(-3.64988, 1.75032, -4.24658, -4.32198, -2.09586, -9.45958);
	hull.cubicTo(-1.46614, -10.9642, -0.71474, -12.04944, 0, -12.04944);
	hull.cubicTo(0.71474, -12.04944, 1.46614, -10.9642, 2.09586, -9.45958);
	hull.cubicTo(4.24658, -4.32198, 3.64988, 1.75032, 3.07996, 7.14766);
	hull.cubicTo(2.70296, 10.7172, 2.06206, 13, 0, 13);

	shipView.push_back(ShipViewElement(hull, QColor(Qt::white), QPen(QColor(Qt::black),0.208)));

	QPainterPath structures;

	structures.moveTo(-1.67908, -7.7129);
	structures.lineTo(-0.98878, -7.7129);
	structures.lineTo(-0.98878, -8.42426);
	structures.lineTo(-1.67908, -8.42426);
	structures.closeSubpath();


	structures.moveTo(0.98852, -7.7129);
	structures.lineTo(1.67908, -7.7129);
	structures.lineTo(1.67908, -8.42426);
	structures.lineTo(0.98852, -8.42426);
	structures.closeSubpath();

	structures.moveTo(2.65226, -4.23436);
	structures.lineTo(2.65226, -2.99468);
	structures.lineTo(1.63202, -2.99468);
	structures.lineTo(1.63202, -2.2516);
	structures.lineTo(-1.63202, -2.2516);
	structures.lineTo(-1.63202, -2.99468);
	structures.lineTo(-2.65226, -2.99468);
	structures.lineTo(-2.65226, -4.23436);
	structures.cubicTo(-2.65226, -6.02264, -2.08182, -7.47292, 0, -7.47292);
	structures.cubicTo(2.08182, -7.47292, 2.65226, -6.02264, 2.65226, -4.23436);

	structures.moveTo(0.00156, -7.26492);
	structures.cubicTo(0.31252, -7.26492, 0.35178, -7.2657, 0.27898, -7.10476);
	structures.cubicTo(0.01066, -6.513, -0.00572, -6.5754, -0.27586, -7.10476);
	structures.cubicTo(-0.35568, -7.26102, -0.30966, -7.26492, 0.00156, -7.26492);

	structures.moveTo(-2.16554, -3.45514);
	structures.lineTo(-1.47524, -3.45514);
	structures.lineTo(-1.47524, -4.64776);
	structures.lineTo(-2.16554, -4.64776);
	structures.closeSubpath();

	structures.moveTo(1.47524, -3.45514);
	structures.lineTo(2.16554, -3.45514);
	structures.lineTo(2.16554, -4.64776);
	structures.lineTo(1.47524, -4.64776);
	structures.closeSubpath();

	structures.moveTo(0.31382, -3.2253);
	structures.cubicTo(0.31382, -3.35816, 0.17316, -3.4658, 0, -3.4658);
	structures.cubicTo(-0.17342, -3.4658, -0.31382, -3.35816, -0.31382, -3.2253);
	structures.cubicTo(-0.31382, -3.09244, -0.17342, -2.9848, 0, -2.9848);
	structures.cubicTo(0.17316, -2.9848, 0.31382, -3.09244, 0.31382, -3.2253);

	structures.moveTo(2.65226, -2.99468);
	structures.lineTo(2.65226, 3.49778);
	structures.lineTo(-2.65226, 3.49778);
	structures.lineTo(-2.65226, -2.99468);

	structures.moveTo(-1.12476, -0.72462);
	structures.lineTo(1.1245, -0.72462);

	structures.moveTo(-2.43308, 8.09952);
	structures.lineTo(-1.74252, 8.09952);
	structures.lineTo(-1.74252, 7.38764);
	structures.lineTo(-2.43308, 7.38764);
	structures.closeSubpath();

	structures.moveTo(1.74252, 8.09952);
	structures.lineTo(2.43308, 8.09952);
	structures.lineTo(2.43308, 7.38764);
	structures.lineTo(1.74252, 7.38764);
	structures.closeSubpath();

	structures.moveTo(-1.33406, -8.24148);
	structures.cubicTo(-1.23864, -8.24148, -1.16142, -8.16426, -1.16142, -8.06884);
	structures.cubicTo(-1.16142, -7.97368, -1.23864, -7.89646, -1.33406, -7.89646);
	structures.cubicTo(-1.42922, -7.89646, -1.50644, -7.97368, -1.50644, -8.06884);
	structures.cubicTo(-1.50644, -8.16426, -1.42922, -8.24148, -1.33406, -8.24148);

	structures.moveTo(1.3338, -8.24148);
	structures.cubicTo(1.42922, -8.24148, 1.50644, -8.16426, 1.50644, -8.06884);
	structures.cubicTo(1.50644, -7.97368, 1.42922, -7.89646, 1.3338, -7.89646);
	structures.cubicTo(1.23838, -7.89646, 1.16116, -7.97368, 1.16116, -8.06884);
	structures.cubicTo(1.16116, -8.16426, 1.23838, -8.24148, 1.3338, -8.24148);

	structures.moveTo(-2.0878, 7.57094);
	structures.cubicTo(-1.99238, 7.57094, -1.91516, 7.64816, -1.91516, 7.74358);
	structures.cubicTo(-1.91516, 7.839, -1.99238, 7.91622, -2.0878, 7.91622);
	structures.cubicTo(-2.18322, 7.91622, -2.26044, 7.839, -2.26044, 7.74358);
	structures.cubicTo(-2.26044, 7.64816, -2.18322, 7.57094, -2.0878, 7.57094);

	structures.moveTo(2.0878, 7.57094);
	structures.cubicTo(2.18296, 7.57094, 2.26018, 7.64816, 2.26018, 7.74358);
	structures.cubicTo(2.26018, 7.839, 2.18296, 7.91622, 2.0878, 7.91622);
	structures.cubicTo(1.99238, 7.91622, 1.91516, 7.839, 1.91516, 7.74358);
	structures.cubicTo(1.91516, 7.64816, 1.99238, 7.57094, 2.0878, 7.57094);

	

	shipView.push_back(ShipViewElement(structures, QBrush(), QPen()));

	QPainterPath gig;

	gig.moveTo(-1.16506, 4.77282);
	gig.lineTo(1.16506, 4.77282);
	gig.lineTo(1.16506, 5.94984);
	gig.cubicTo(1.26724, 5.95322, 1.36058, 5.90018, 1.42298, 5.84064);
	gig.cubicTo(1.42298, 5.99482, 1.42298, 6.149, 1.42298, 6.30318);
	gig.cubicTo(1.36058, 6.24364, 1.26724, 6.19086, 1.16506, 6.19398);
	gig.lineTo(1.16506, 6.31332);
	gig.lineTo(0.64246, 6.31332);
	gig.lineTo(0.64246, 6.85204);
	gig.cubicTo(0.74464, 6.85516, 0.83798, 6.80212, 0.90038, 6.74258);
	gig.cubicTo(0.90038, 6.89676, 0.90038, 7.05094, 0.90038, 7.20512);
	gig.cubicTo(0.83798, 7.14584, 0.74464, 7.0928, 0.64246, 7.09592);
	gig.lineTo(0.64246, 8.08002);
	gig.lineTo(-0.64246, 8.08002);
	gig.lineTo(-0.64246, 7.09592);
	gig.cubicTo(-0.74464, 7.0928, -0.83798, 7.14584, -0.90038, 7.20512);
	gig.cubicTo(-0.90038, 7.05094, -0.90038, 6.89676, -0.90038, 6.74258);
	gig.cubicTo(-0.83798, 6.80212, -0.74464, 6.85516, -0.64246, 6.85204);
	gig.lineTo(-0.64246, 6.31332);
	gig.lineTo(-1.16506, 6.31332);
	gig.lineTo(-1.16506, 6.19398);
	gig.cubicTo(-1.26724, 6.19086, -1.36058, 6.24364, -1.42298, 6.30318);
	gig.cubicTo(-1.42298, 6.149, -1.42298, 5.99482, -1.42298, 5.84064);
	gig.cubicTo(-1.36058, 5.90018, -1.26724, 5.95322, -1.16506, 5.94984);
	gig.lineTo(-1.16506, 4.77282);

	gig.moveTo(0, -10.62152);
	gig.cubicTo(0.46228, -10.62152, 0.83694, -10.24686, 0.83694, -9.78484);
	gig.cubicTo(0.83694, -9.32256, 0.46228, -8.9479, 0, -8.9479);
	gig.cubicTo(-0.46228, -8.9479, -0.83694, -9.32256, -0.83694, -9.78484);
	gig.cubicTo(-0.83694, -10.24686, -0.46228, -10.62152, 0, -10.62152);

	shipView.push_back(ShipViewElement(gig,QColor(0, 0, 0),QPen()));

	QPainterPath funnel;

	funnel.moveTo(0, -0.07618);
	funnel.cubicTo(0.80886, -0.07618, 1.46458, 0.57954, 1.46458, 1.3884);
	funnel.cubicTo(1.46458, 2.19726, 0.80886, 2.85298, 0, 2.85298);
	funnel.cubicTo(-0.80886, 2.85298, -1.46458, 2.19726, -1.46458, 1.3884);
	funnel.cubicTo(-1.46458, 0.57954, -0.80886, -0.07618, 0, -0.07618);


	shipView.push_back(ShipViewElement(funnel, QBrush(), QPen(QColor(Qt::black),0.208)));
}

Render2D::~Render2D()
{

}

QSize Render2D::minimumSizeHint() const
{
    return QSize(300, 300);
}

QSize Render2D::sizeHint() const
{
    return QSize(300, 300);
}

int Render2D::heightForWidth (int w) const
{
	return w;
}

void Render2D::setShipRenderData(const ShipRenderData& shipRenderData)
{
	this->shipRenderData = shipRenderData;

	if(traceShip)
	{
		viewPos.setX(shipRenderData.x);
		viewPos.setY(shipRenderData.y);
	}

	if(shipPrints.size() != 0)
	{
		if(shipRenderData.timeStamp - shipPrints.last().timeStamp >= printsDT)
			shipPrints.push_back(shipRenderData);
	}
	else
		shipPrints.push_back(shipRenderData);

	if(shipPrints.size() > printsNum)
		shipPrints.removeFirst();
}

void Render2D::traceStateChanged(int state)
{
	traceShip = state;

	if(traceShip)
	{
		viewPos.setX(shipRenderData.x);
		viewPos.setY(shipRenderData.y);
	}
}

void Render2D::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing, true);

	for(int i = 0; i != shipPrints.size(); ++i)
	{
		painter.resetTransform();
		painter.scale(scaleFactor,scaleFactor);
		painter.translate(shipPrints[i].y-viewPos.y()+width()/2.0/scaleFactor, viewPos.x()-shipPrints[i].x+height()/2.0/scaleFactor);	
		painter.rotate(shipPrints[i].course);
		drawPrint(painter);
	}

	painter.resetTransform();
	painter.scale(scaleFactor,scaleFactor);
	painter.translate(shipRenderData.y-viewPos.y()+width()/2.0/scaleFactor, viewPos.x()-shipRenderData.x+height()/2.0/scaleFactor);	
	painter.rotate(shipRenderData.course);
	drawShip(painter);
}

void Render2D::timerEvent(QTimerEvent *e)
{
	update();
}

void Render2D::wheelEvent(QWheelEvent *event)
{
	scaleFactor *= event->delta() > 0 ? 0.9: 1.1;
}

void Render2D::mousePressEvent(QMouseEvent *e)
{
	lastViewPos = e->pos();
}

void Render2D::mouseMoveEvent(QMouseEvent *e)
{
	if(traceShip)
		return;

	if (e->buttons() & Qt::LeftButton)
	{
		int dx = e->x() - lastViewPos.x();
		int dy = e->y() - lastViewPos.y();

		viewPos.setX(viewPos.x() + dy/scaleFactor);
		viewPos.setY(viewPos.y() - dx/scaleFactor);
	}
	lastViewPos = e->pos();
	update();
}

void Render2D::drawShip(QPainter& painter)
{
	for(int i = 0; i != shipView.size(); ++i)
	{
		painter.setBrush(shipView[i].brush);
		painter.setPen(shipView[i].pen);
		painter.drawPath(shipView[i].path);
	}
}

void Render2D::drawPrint(QPainter& painter)
{
	painter.setBrush(QBrush());
	QPen pen;
	pen.setStyle(Qt::DashLine);
	painter.setPen(pen);

	QPainterPath hull;

	hull.moveTo(0, 13);
	hull.cubicTo(-2.06206, 13, -2.70296, 10.7172, -3.07996, 7.14766);
	hull.cubicTo(-3.64988, 1.75032, -4.24658, -4.32198, -2.09586, -9.45958);
	hull.cubicTo(-1.46614, -10.9642, -0.71474, -12.04944, 0, -12.04944);
	hull.cubicTo(0.71474, -12.04944, 1.46614, -10.9642, 2.09586, -9.45958);
	hull.cubicTo(4.24658, -4.32198, 3.64988, 1.75032, 3.07996, 7.14766);
	hull.cubicTo(2.70296, 10.7172, 2.06206, 13, 0, 13);

	painter.drawPath(hull);
}